package com.eastdigit.shiro.filter;

import java.util.UUID;

import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.eastdigit.servlet.ReqBean;
import com.eastdigit.shiro.GlobalInput;
import com.eastdigit.shiro.ShiroConstants;
import com.eastdigit.shiro.authc.StatelessToken;
import com.eastdigit.shiro.cache.StateTokenCache;

public class StatelessAuthcFilter extends StateAuthcFilter {
	
	@Autowired
    private StateTokenCache stateTokenCache;
    
    protected boolean isLoginRequest(ServletRequest request, ServletResponse response){
    	String url = ((HttpServletRequest) request).getServletPath();
    	return url.contains(getLoginUrl()) || url.contains(whbusLoginUrl) ;
    }
    
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    	ReqBean reqBean = (ReqBean) request.getAttribute(ReqBean.NAME);
        reqBean.setStateless(true);
        if (isLoginRequest(request, response)) {// 如果是登录请求，则返回false提交给登录校验，不然不重新登录
            return false;
        } else {
        	AuthenticationToken token = stateTokenCache.getToken(reqBean.getToken());
        	if(token instanceof StatelessToken){
        		StatelessToken _token = (StatelessToken)token;
        		this.getSubject(request, response).login(_token);
        		return this.getSubject(request, response).isAuthenticated();
        	}else{
        		return false;
        	}
        }
    }
    
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
            ServletResponse response) throws Exception {
    	String _token =  UUID.randomUUID().toString();
    	stateTokenCache.cacheToken(_token, token);
    	ReqBean reqBean = (ReqBean) request.getAttribute(ReqBean.NAME);
    	reqBean.setToken(_token);
        return true;
    }

    @Override
    protected void executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
    	if(isLoginRequest(request, response)){
    		RequestDispatcher rd = request.getRequestDispatcher(getSuccessUrl());
            rd.forward(request, response);
            return;
    	}else if(this.getSubject(request, response).isAuthenticated()){
    		ReqBean reqBean = (ReqBean) request.getAttribute(ReqBean.NAME);
            if (reqBean != null) {// 这里可能没有经过MainFilter
                try {
                    reqBean.setUserId(GlobalInput.getCurrentUserId());
                } catch (Exception e) {
                    ((HttpServletResponse) response).sendError(871202);
                }
            }
            String url = ((HttpServletRequest) request).getServletPath();
            if(url.startsWith(ShiroConstants.PREFIX_STATELESS)){
            	RequestDispatcher rd = request.getRequestDispatcher(url.substring(ShiroConstants.PREFIX_STATELESS.length() - 1));
        		rd.forward(request, response);
        		return;
            }
            super.executeChain(request, response, chain);
    	}else {
    		((HttpServletResponse) response).sendError(871202);
    	}
    }
}
